import datetime
from multiprocessing import Process

from flask import current_app
from flask_apscheduler import APScheduler

from db.dao import StockInfoDao, StockSpiderMarkDao, StockHoldersDao, StockFundsHolderDao, MarketWorkDayDao
from db.models import StockSpiderMark
from service.requests.Eastmoney import Eastmoney
from service.text_analysis.NewsService import analysis
from spiders.scrapy_trigger import market, industry, stock_funds_1, stock_funds_2, importIndustryGuid, \
    importIndustryResearch, importIndustryInformation, getWorkday
from task.spider_task import industry_growth_list, stock_pool_monitor, concept_ranking_list
from utils.holiday_util import HolidayUtil
from utils.util import ObjDictTool, CommonUtil

scheduler = APScheduler()


def create_task(app):
    scheduler.init_app(app)
    scheduler.start()


@scheduler.task('cron', id='import_market1', day='*', hour='16', minute='01', second='00', timezone='Asia/Shanghai')
@scheduler.task('cron', id='import_market2', day='*', hour='15', minute='02', second='00', timezone='Asia/Shanghai')
def import_market():
    '''
    下载市场行情
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------market start-----')
        if MarketWorkDayDao().judgeWorkDay(datetime.date.today()):
            p = Process(target=market)
            p.start()
            p.join()
            current_app.logger.info("-------- market end----------")
        else:
            current_app.logger.info('非工作日')


# @scheduler.task('cron', id='init_stockMark', day='*', hour='01', minute='00', second='00', timezone='Asia/Shanghai')
def initStockMark():
    '''
    初始化股票标识，
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------ init stock mark start -----')
        if HolidayUtil.is_tradingDay(datetime.datetime.today()):
            stock_list = StockInfoDao().findAll()
            if stock_list:
                for stock in stock_list:
                    mark = StockSpiderMark()
                    setattr(mark, 'stock_code', getattr(stock, 'stock_code'))
                    setattr(mark, 'trading_date', datetime.datetime.today())
                    StockSpiderMarkDao().saveOrUpdate(mark)
            current_app.logger.info("-------- init stock mark  end----------")
        else:
            current_app.logger.info('非工作日')


@scheduler.task('cron', id='import_industry_1', day='*', hour='16', minute='39', second='00', timezone='Asia/Shanghai')
@scheduler.task('cron', id='import_industry_2', day='*', hour='15', minute='05', second='00', timezone='Asia/Shanghai')
def import_industry():
    '''
    下载行业行情
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- industry start -----')
        if MarketWorkDayDao().judgeWorkDay(datetime.date.today()):
            p = Process(target=industry)
            p.start()
            p.join()
            current_app.logger.info("---------- industry end -----------")
        else:
            current_app.logger.info('非工作日')


# @scheduler.task('cron', id='importStockFunds1_1', day='*', hour='20', minute='50', second='00',
#                 timezone='Asia/Shanghai')
# @scheduler.task('cron', id='importStockFunds1_2', day='*', hour='15', minute='50', second='00', day_of_week='mon-fri',
#                 timezone='Asia/Shanghai')
def importStockFunds1():
    '''
    job4: 每天的13:26:05时刻执行一次函数
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- stock1 start-----')
        if MarketWorkDayDao().judgeWorkDay(datetime.date.today()):
            p_list = []
            stock_list = StockInfoDao().findNoSpiderStocks(
                create_date=MarketWorkDayDao().queryLastWorkDay(datetime.date.today()),
                stock_funds_1=1, stock_funds_2=None)
            # stock_list = StockInfoDao().findNoSpiderStocks(create_date=get_date_str(0), stock_funds_1=1)
            if stock_list:
                chunks_list = ObjDictTool.chunks(stock_list, 3)
                for chunk in chunks_list:
                    p = Process(target=stock_funds_1, args=tuple(chunk))
                    p.start()
                    p_list.append(p)
                for p1 in p_list:
                    p1.join()
            current_app.logger.info("----------- stock1 end -----------")
        else:
            current_app.logger.info('非工作日')


# @scheduler.task('cron', id='importStockFunds2_1', day='*', hour='16', minute='30', second='00',
#                 timezone='Asia/Shanghai')
# @scheduler.task('cron', id='importStockFunds2_2', day='*', hour='21', minute='20', second='00',
#                 timezone='Asia/Shanghai')
def importStockFunds2():
    '''
    job4: 每天的13:26:05时刻执行一次函数
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- stock2 start -----')
        if MarketWorkDayDao().judgeWorkDay(datetime.date.today()):
            p_list = []
            stock_list = StockInfoDao().findNoSpiderStocks(
                create_date=MarketWorkDayDao().queryLastWorkDay(datetime.date.today()),
                stock_funds_1=None, stock_funds_2=1)
            # stock_list = StockInfoDao().findNoSpiderStocks(create_date=get_date_str(0), stock_funds_2=1)
            if stock_list:
                chunks_list = ObjDictTool.chunks(stock_list, 3)
            for chunk in chunks_list:
                p = Process(target=stock_funds_2, args=tuple(chunk))
                p.start()
                p_list.append(p)
            for p1 in p_list:
                p1.join()
            current_app.logger.info("------------ stock2 end ------------")
        else:
            current_app.logger.info("非工作日")


@scheduler.task('cron', id='importStockFundsHolder_1', day_of_week='mon-fri', hour='09-11', minute='*/10',
                second='50',
                timezone='Asia/Shanghai')
@scheduler.task('cron', id='importStockFundsHolder_2', day_of_week='mon-fri', hour='13-15', minute='*/10',
                second='50',
                timezone='Asia/Shanghai')
# @scheduler.task('cron', id='importIndustryGrowthList_', day='*', hour='16', minute='05', second='21', timezone='Asia/Shanghai')
def importStockFundsHolder():
    '''
    拉取持股股票的行情
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- stock_funds_holder start -----')
        if MarketWorkDayDao().judgeWorkDay(datetime.date.today()):
            if not (CommonUtil.timeIninterval() or CommonUtil.timeIninterval(start_time='13:00:00',
                                                                             end_time='15:01:00')):
                return
            stock_list = StockHoldersDao().findAll()
            if stock_list:
                for stock in stock_list:
                    fund = Eastmoney.get_realtime_quotes(getattr(stock, 'stock_code'))
                    StockFundsHolderDao().save(fund)
            current_app.logger.info("------------ stock_funds_holder end ------------")
        else:
            current_app.logger.info("非工作日")


@scheduler.task('interval', id='importIndustryGuidNews', hours=2, timezone='Asia/Shanghai')
def importIndustryGuidNews():
    '''
    导入行业导读新闻
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- 爬取行业导读新闻任务开始 -----')
        p = Process(target=importIndustryGuid)
        p.start()
        p.join()
        current_app.logger.info("------------ 爬取行业导读新闻任务结束 ------------")


@scheduler.task('interval', id='importIndustryResearchNews', hours=2, timezone='Asia/Shanghai')
def importIndustryResearchNews():
    '''
    下载行业研读新闻
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- 爬取行业研究新闻任务开始 -----')
        p = Process(target=importIndustryResearch)
        p.start()
        p.join()
        current_app.logger.info("------------ 爬取行业研究新闻任务结束 ------------")


@scheduler.task('interval', id='importIndustryInformationNews', hours=2, timezone='Asia/Shanghai')
def importIndustryInformationNews():
    '''
    下载行业资讯
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- 爬取行业资讯任务开始 -----')
        p = Process(target=importIndustryInformation)
        p.start()
        p.join()
        current_app.logger.info("------------ 爬取行业资讯任务结束 ------------")


@scheduler.task('interval', id='extractkeysNews', hours=3, timezone='Asia/Shanghai')
def extract_keys_news():
    '''
    提取新闻关键字
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- 提取新闻关键字任务开始 -----')
        analysis(None)
        current_app.logger.info("------------ 提取新闻关键字任务结束 ------------")


@scheduler.task('cron', id='importIndustryGrowthList_1', day_of_week='mon-fri', hour='09-11', minute='*/30',
                second='10',
                timezone='Asia/Shanghai')
@scheduler.task('cron', id='importIndustryGrowthList_2', day_of_week='mon-fri', hour='13-15', minute='*/30',
                second='10',
                timezone='Asia/Shanghai')
# @scheduler.task('cron', id='importIndustryGrowthList_2', day='*', hour='02', minute='00', second='21', timezone='Asia/Shanghai')
def importIndustryGrowthList():
    '''
    每半小时获取行业排行榜
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------- 获取行业排行榜开始 -----')
        if MarketWorkDayDao().judgeWorkDay(datetime.date.today()):
            concept_ranking_list()

            industry_growth_list()
            stock_pool_monitor()
        else:
            current_app.logger.info("------------ 当前非工作日 ------------")

        current_app.logger.info("------------ 获取行业排行榜结束 ------------")


@scheduler.task('cron', id='market_open1', day='*', day_of_week='mon-fri', hour='09', minute='15', second='05',
                timezone='Asia/Shanghai')
@scheduler.task('cron', id='market_open2', day='*', day_of_week='mon-fri', hour='09', minute='30', second='05',
                timezone='Asia/Shanghai')
def market_open():
    '''
    大盘开市时间
    :return:
    '''
    with scheduler.app.app_context():
        current_app.logger.info('------workday start-----')
        p = Process(target=getWorkday)
        p.start()
        p.join()
        current_app.logger.info("-------- workday end----------")
